package cn.iocoder.yudao.module.call.service.statistics;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.module.call.controller.admin.statistics.vo.CallStatisticsChannelRankRespVO;
import cn.iocoder.yudao.module.call.controller.admin.statistics.vo.CallStatisticsRankReqVO;
import cn.iocoder.yudao.module.call.controller.admin.statistics.vo.CallStatisticsRankRespVO;
import cn.iocoder.yudao.module.call.dal.dataobject.channel.ChannelDO;
import cn.iocoder.yudao.module.call.dal.mysql.statistics.CallStatisticsRankingMapper;
import cn.iocoder.yudao.module.call.service.channel.ChannelService;
import cn.iocoder.yudao.module.system.api.dept.DeptApi;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.function.Function;

import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;

/**
 * CRM 排行榜统计 Service 实现类
 *
 * @author anhaohao
 */
@Service
@Validated
public class CallStatisticsRankingServiceImpl implements CallStatisticsRankingService {

    @Resource
    private CallStatisticsRankingMapper rankMapper;

    @Resource
    private AdminUserApi adminUserApi;
    @Resource
    private DeptApi deptApi;
    @Resource
    private ChannelService channelService;

    @Override
    public List<CallStatisticsRankRespVO> getCallCountRank(CallStatisticsRankReqVO rankReqVO) {
        return getRank(rankReqVO, rankMapper::selectCallCountRank);
    }

    @Override
    public List<CallStatisticsRankRespVO> getSuccessCountRank(CallStatisticsRankReqVO rankReqVO) {
        return getRank(rankReqVO, rankMapper::selectSuccessCountRank);
    }

    @Override
    public List<CallStatisticsRankRespVO> getCallSecondRank(CallStatisticsRankReqVO rankReqVO) {
        return getRank(rankReqVO, rankMapper::selectCallSecondRank);
    }

    @Override
    public List<CallStatisticsChannelRankRespVO> getCallChannelRank(CallStatisticsRankReqVO rankReqVO) {
        // 1. 获得用户编号数组
        rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId()));
        if (CollUtil.isEmpty(rankReqVO.getUserIds())) {
            return Collections.emptyList();
        }
        // 2. 获得排行数据
        List<CallStatisticsChannelRankRespVO> ranks = rankMapper.selectCallChannelRank(rankReqVO);
        Map<Long, ChannelDO> channelMap = channelService.getChannelMap(convertSet(ranks, CallStatisticsChannelRankRespVO::getChannelId));
        ranks.forEach(rank -> MapUtils.findAndThen(channelMap, rank.getChannelId(), channel -> {
            rank.setChannelName(channel.getName());
        }));
        ranks.sort(Comparator.comparing(CallStatisticsChannelRankRespVO::getCount).reversed());

        return ranks;

    }


    /**
     * 获得排行版数据
     *
     * @param rankReqVO    参数
     * @param rankFunction 排行榜方法
     * @return 排行版数据
     */
    private List<CallStatisticsRankRespVO> getRank(CallStatisticsRankReqVO rankReqVO, Function<CallStatisticsRankReqVO, List<CallStatisticsRankRespVO>> rankFunction) {
        // 1. 获得用户编号数组
        rankReqVO.setUserIds(getUserIds(rankReqVO.getDeptId()));
        if (CollUtil.isEmpty(rankReqVO.getUserIds())) {
            return Collections.emptyList();
        }
        // 2. 获得排行数据
        List<CallStatisticsRankRespVO> ranks = rankFunction.apply(rankReqVO);
        if (CollUtil.isEmpty(ranks)) {
            return Collections.emptyList();
        }
        ranks.sort(Comparator.comparing(CallStatisticsRankRespVO::getCount).reversed());
        // 3. 拼接用户信息
        appendUserInfo(ranks);
        return ranks;
    }


    /**
     * 拼接用户信息（昵称、部门）
     *
     * @param ranks 排行榜数据
     */
    private void appendUserInfo(List<CallStatisticsRankRespVO> ranks) {
        Map<Long, AdminUserRespDTO> userMap = adminUserApi.getUserMap(convertSet(ranks, CallStatisticsRankRespVO::getOwnerUserId));
        Map<Long, DeptRespDTO> deptMap = deptApi.getDeptMap(convertSet(userMap.values(), AdminUserRespDTO::getDeptId));

        ranks.forEach(rank -> MapUtils.findAndThen(userMap, rank.getOwnerUserId(), user -> {
            rank.setNickname(user.getNickname());
            MapUtils.findAndThen(deptMap, user.getDeptId(), dept -> rank.setDeptName(dept.getName()));
        }));
    }

    /**
     * 获得部门下的用户编号数组，包括子部门的
     *
     * @param deptId 部门编号
     * @return 用户编号数组
     */
    public List<Long> getUserIds(Long deptId) {
        // 1. 获得部门列表
        List<Long> deptIds = convertList(deptApi.getChildDeptList(deptId), DeptRespDTO::getId);
        deptIds.add(deptId);
        // 2. 获得用户编号
        return convertList(adminUserApi.getUserListByDeptIds(deptIds), AdminUserRespDTO::getId);
    }

}